﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using System.Collections.ObjectModel;
using System.Threading;
using System.Text.RegularExpressions;

namespace SharePointManagementStudio
{
    public partial class frmSolutionDeployer : Form
    {

        List<string> WebApps = new List<string>();
        List<string> WebAppsredp = new List<string>();
        List<string> Global = new List<string>();
        List<string> Globalredp = new List<string>();

        public frmSolutionDeployer()
        {
            InitializeComponent();
            InitializeBackgroundWorkers();
        }


        private void InitializeBackgroundWorkers()
        {
            backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
            backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
        }

        // Deployment
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            if (WebApps.Count > 0)
            {
                Collection<SPWebApplication> webappslist = new Collection<SPWebApplication>();
                foreach (string itm in WebApps)
                {
                    appendText("Repering " + itm.ToString()  + " to deploy\n");
                    this.BeginInvoke(new MethodInvoker(delegate()
                    {
                        foreach (object o in this.chkFarmApplications.CheckedItems)
                        {
                            SPWebApplication webapp = SPWebApplication.Lookup(new Uri(o.ToString()));
                            webappslist.Add(webapp);
                        }
                    }));
                    SPSolution s = SPFarm.Local.Solutions[itm.ToString()];
                    if (s.JobExists == true)
                    {
                        KillRunningJobs(s);
                    }
                    s.Deploy(DateTime.Now, false, webappslist, true);
                    appendText(itm.ToString()  + " The solution was successfully deployed.\n");
                }                          
            }

            if (Global.Count > 0)
            {
                for (int i = 0; i <= Global.Count-1; i++)
                {
                    Console.WriteLine(Global[i].ToString());
                    SPSolution s = SPFarm.Local.Solutions[Global[i].ToString()];
                    if (s.JobExists == true)
                    {
                        KillRunningJobs(s);
                    }                    
                    s.Deploy(DateTime.Now, true, true);
                    appendText(s.DisplayName.ToString() + " The solution was successfully deployed.(GLOBAL DEPLOY)\n");  
                }
            }
           
            if (Globalredp.Count > 0)
            {
                foreach (string itm in Globalredp)
                {
                    SPSolution s = SPFarm.Local.Solutions[itm.ToString()];
                    if (s.JobExists == true)
                    {
                        KillRunningJobs(s);
                    }
                    appendText("Begin Redeployin.");
                    s.Retract(DateTime.Now);
                basla:
                    Thread.Sleep(4000);
                    appendText(".");
                    try
                    {
                        s.Deploy(DateTime.Now, true, true);
                        appendText(s.DisplayName.ToString() + " The solution was successfully deployed.(GLOBAL DEPLOY)\n");
                    }
                    catch
                    {
                        appendText(".");
                        goto basla;
                    }
                }
            }

            if (WebAppsredp.Count > 0)
            {
                for (int i = 0; i <= WebAppsredp.Count - 1; i++)
                {
                    SPSolution s = SPFarm.Local.Solutions[WebAppsredp[i].ToString()];
                    if (s.JobExists == true)
                    {
                        KillRunningJobs(s);
                    }
                    List<string> RedeployWeb = new List<string>(); 
                    foreach (SPWebApplication web in s.DeployedWebApplications)
                    {
                        RedeployWeb.Add(web.Sites[0].RootWeb.Url.ToString());
                        appendText("Repering deploy for" + web.Sites[0].RootWeb.Url.ToString() + "\n");    
                    }
                    foreach (object itm in this.chkFarmApplications.CheckedItems)
                    {
                        if (RedeployWeb.Contains(itm.ToString()) == false)
                        {
                            RedeployWeb.Add(itm.ToString());
                            appendText("Repering deploy for" + itm.ToString()+"\n");    
                        }
                    }

                    if (s.JobExists == true)
                    {
                        KillRunningJobs(s);
                    }
                    appendText(s.DisplayName.ToString() + " Redeployin..\n");
                    s.Retract(DateTime.Now,s.DeployedWebApplications);

                    Collection<SPWebApplication> rewebapps = new Collection<SPWebApplication>();

                    foreach (string itm in RedeployWeb)
                    {
                        SPWebApplication webapp = SPWebApplication.Lookup(new Uri(itm.ToString()));
                        rewebapps.Add(webapp);
                        appendText("Repering deploy for" + itm.ToString() + "\n");        
                    }

                    if (s.JobExists == true)
                    {
                        KillRunningJobs(s);
                    }
                    s.Deploy(DateTime.Now, false, rewebapps, true);
                    appendText(s.DisplayName.ToString() + " Deployed Succesfuly.\n");  
                }
            }
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            toolStripProgressBar1.Value = 100;
            toolStripProgressBar1.Value = 0;
            timer1.Stop();           
        }

       

      
 

        private void btnRemoveSelect_Click(object sender, EventArgs e)
        {
            for (int i = this.chkBoxFiles.Items.Count - 1; i >= 0; i--)
            {
                if (this.chkBoxFiles.GetItemChecked(i))
                {
                    this.chkBoxFiles.Items.RemoveAt(i);
                }
            }           
        }

 

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (toolStripProgressBar1.Value == toolStripProgressBar1.Maximum)
            {
                toolStripProgressBar1.Value = 0;
            }
            toolStripProgressBar1.PerformStep();
        }

     
        private void KillRunningJobs(SPSolution solution)
        {
            if (solution == null) return;

            try
            {
                if (solution.JobExists)
                {
                    // is the job already running
                    //if (solution.JobStatus == SPRunningJobStatus.Initialized)
                    //{
                    //    throw new Exception("A deployment job already running for this solution.");
                    //}

                    // find the running job
                    SPJobDefinition definition = null;
                    foreach (SPJobDefinition jobdefs in SPFarm.Local.TimerService.JobDefinitions)
                    {
                        if ((jobdefs.Title != null) && jobdefs.Title.Contains(solution.Name))
                        {
                            definition = jobdefs;
                            break;
                        }
                    }

                    if (definition != null)
                    {
                        definition.Delete();    // kill if it was found
                        Thread.Sleep(1000);     // give it time to delete
                    }
                }
            }
            catch (Exception ee)
            {
                //throw new Exception("Error while trying to kill running jobs.", ee);
            }
        }


       
      

       
   

        private void appendText(string p)
        {
            this.BeginInvoke(new MethodInvoker(delegate()
            {
                this.richTextBox1.Text += p;
            }));
        }

        private string getsolutionname(string p)
        {
            string tmpname = p;
            string[] name = tmpname.Split('\\');
            return name[name.Length - 1].ToString();
        }

      
   

       private void toolStripButtonLoadFiles_Click(object sender, EventArgs e)
       {
           DialogResult dr = this.openFileDialog1.ShowDialog();
           if (dr == System.Windows.Forms.DialogResult.OK)
           {
               // Read the files
               foreach (String file in openFileDialog1.FileNames)
               {
                   this.chkBoxFiles.Items.Add(file);
               }
           }
       }

       private void toolStripButtonConnect_Click(object sender, EventArgs e)
       {
                SPFarm spf = SPFarm.Local;
                SPWebService spws = spf.Services.GetValue<SPWebService>("");
                int sitecount = spws.WebApplications.Count;

                foreach (SPWebApplication spwa in spws.WebApplications)
                {
                    try
                    {
                        chkFarmApplications.Items.Add(spwa.Sites[0].RootWeb.Url.ToString());                        
                    }
                    catch
                    {
                        //   AppendText("error accured when connect to :" + spwa.Name.ToString() + " site collection is not found or site correpted.\n"); 
                    }
                }
       }

       private void checkBoxSolutions_CheckedChanged(object sender, EventArgs e)
       {
           for (int i = 0; i < this.chkBoxFiles.Items.Count; i++)
           {
               if (checkBoxSolutions.Checked == true)
               {
                   this.chkBoxFiles.SetItemChecked(i, true);
               }
               else
               {
                   this.chkBoxFiles.SetItemChecked(i, false);
               }
           }
       }

       private void checkBoxWebApps_CheckedChanged(object sender, EventArgs e)
       {
           for (int i = 0; i < this.chkFarmApplications.Items.Count; i++)
           {
               if (checkBoxWebApps.Checked == true)
               {
                   this.chkFarmApplications.SetItemChecked(i, true);
               }
               else
               {
                   this.chkFarmApplications.SetItemChecked(i, false);
               }
           }
       }

  

       private void btnDeployWeb_Click(object sender, EventArgs e)
       {
           if (chkBoxFiles.CheckedItems.Count == 0)
           {
               MessageBox.Show("Select one or more solution files to deploy", "warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
           }
           else 
           {
                foreach (Object itm in this.chkBoxFiles.CheckedItems)
                {
                        SPSolution s = SPFarm.Local.Solutions[getsolutionname(itm.ToString())];
                        try
                        {
                            if (s.Deployed == true) { }
                        }catch 
                        {                            
                            SPSolution snew = SPFarm.Local.Solutions.Add(getsolutionname(itm.ToString()));
                            s = snew;
                        }

                            if (s.ContainsWebApplicationResource == true)
                            {
                                if (s.Deployed == true)
                                {
                                    if (MessageBox.Show(s.DisplayName.ToString() + " is allready Deployed\nDo you want redeploy it?", "Confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                                    {
                                        richTextBox1.Text += "\nUser Accecpted Redeploy solution\n";
                                        WebAppsredp.Add(s.DisplayName.ToString());   
                                    }
                                    else 
                                    {
                                        richTextBox1.Text += "\nCancel deployment for " + s.DisplayName.ToString() + "\n"  ; 
                                    }

                                }
                                else
                                {
                                    WebApps.Add(s.DisplayName.ToString());
                                }
                            }
                            else
                            {
                                if (s.Deployed == true)
                                {
                                    if (MessageBox.Show(s.DisplayName.ToString() + " is allready Deployed\nDo you want redeploy it?", "Confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                                    {
                                        richTextBox1.Text += "\nUser Accecpted Redeploy solution\n";
                                        Globalredp.Add(s.DisplayName.ToString());
                                    }
                                    else
                                    {
                                        richTextBox1.Text += "\nCancel deployment for " + s.DisplayName.ToString() + "\n";
                                    }

                                }
                                else
                                {
                                    Global.Add(s.DisplayName.ToString());
                                }
                            }

                }


                if (WebApps.Count > 0 || WebAppsredp.Count > 0)
                {
                    if (chkFarmApplications.CheckedItems.Count == 0)
                    {
                        MessageBox.Show("Your solution files contains Web application deployment option.\nPleace select one or more web application", "warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    }
                    else
                    {
                        timer1.Enabled = true;
                        this.backgroundWorker1.RunWorkerAsync();
                    }
                }

                if (Global.Count > 0 || Globalredp.Count > 0)
                {
                    timer1.Enabled = true;
                    this.backgroundWorker1.RunWorkerAsync();
                 
                }
  
           }
       }
    }
}
